//
// Created by 67678 on 2023/3/13.
//

#include "epoll.h"
#include <stdexcept>
#include <sys/epoll.h>
#include "log.h"

using namespace std;
using namespace socket_epoll;


void Epoll::init() {
    log("epoll initiating!");

    epfd_ = epoll_create(MAX_CONNECTION);
    if (epfd_ == -1) throw runtime_error("epoll create failed!");
}


int Epoll::add(int fd, int state) {
    epoll_event ev;
    ev.events = state;
    ev.data.fd = fd;
    int ret = epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev);
    if (ret == -1) throw runtime_error("epoll_ctl add failed!");
    return ret;
}

int Epoll::mod(int fd, int state) {
    epoll_event ev;
    ev.events = state;
    ev.data.fd = fd;
    return epoll_ctl(epfd_, EPOLL_CTL_MOD, fd, &ev);
}

int Epoll::del(int fd) {
    return epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, nullptr);
}

Epoll::Epoll() {
    log("epoll start running!");
}

void Epoll::close() {
    log("epoll closing!");
    if (epfd_ != -1)
        ::close(epfd_);
}

Epoll::~Epoll() {
    log("epoll end running!");
    close();
}

int Epoll::wait(int timeout) {
    int ret = epoll_wait(epfd_, events_.data(), MAX_CONNECTION, -1);

    if (ret == -1 && errno != EINTR) {
        log(fmt::format("epoll wait failed with code {}, error msg: {}", errno, ::strerror(errno)));
        throw runtime_error("epoll wait failed!");
    }
    return ret;

}
